package org.gp953.order.service.impl;

import org.gp953.basic.exception.BusinessException;
import org.gp953.basic.service.impl.BaseServiceImpl;
import org.gp953.basic.util.CodeGenerateUtils;
import org.gp953.basic.util.PageList;
import org.gp953.order.consts.OrderConsts;
import org.gp953.order.domain.AdoptOrder;
import org.gp953.order.domain.OrderAddress;
import org.gp953.order.mapper.AdoptOrderMapper;
import org.gp953.order.mapper.OrderAddressMapper;
import org.gp953.order.query.AdoptOrderQuery;
import org.gp953.order.service.IAdoptOrderService;
import org.gp953.org.domain.Employee;
import org.gp953.org.mapper.EmployeeMapper;
import org.gp953.pay.constants.Payconsts;
import org.gp953.pay.domain.PayBill;
import org.gp953.pay.service.IPayBillService;
import org.gp953.pet.domain.Pet;
import org.gp953.pet.mapper.PetMapper;
import org.gp953.quartz.consts.QuartzConsts;
import org.gp953.quartz.service.IQuartzService;
import org.gp953.quartz.utils.QuartzJobInfo;
import org.gp953.user.domain.LoginInfo;
import org.gp953.user.domain.User;
import org.gp953.user.domain.UserAddress;
import org.gp953.user.mapper.UserAddressMapper;
import org.gp953.user.mapper.UserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class AdoptOrderServiceImpl extends BaseServiceImpl<AdoptOrder> implements IAdoptOrderService {
    @Autowired
    private PetMapper petMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserAddressMapper userAddressMapper;
    @Autowired
    private AdoptOrderMapper adoptOrderMapper;
    @Autowired
    private OrderAddressMapper orderAddressMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private IPayBillService payBillService;
    @Autowired
    private IQuartzService quartzService;

    @Override
    public String adoptPet(Map<String, Object> map, Long id) {
        // 校验数据
        Integer serviceMethod = Integer.valueOf(map.get("service_method").toString());
        Long addressId = Long.valueOf(map.get("address_id").toString());
        Integer payMethod = Integer.valueOf(map.get("pay_method").toString());
        Long petId = Long.valueOf(map.get("pet_id").toString());
        if (serviceMethod==null
                ||addressId==null
                ||payMethod==null
                ||petId==null){
            throw new BusinessException("订单数据异常");
        }
        // 下架该宠物
        Pet pet = petMapper.loadById(petId);
        User user = userMapper.queryByLoginInfoId(id);
        // 修改状态下架宠物
        pet.setState(0);
        pet.setUser_id(user.getId());
        pet.setOffsaletime(new Date());
        petMapper.update(pet);
        // 生成订单
        AdoptOrder adoptOrder = initAdoptOrder(pet,user,serviceMethod);
        // 返回自增id存放到订单地址表中
        adoptOrderMapper.save(adoptOrder);

        // 生成订单地址表
        // 通过addressId获取用户详细地址
        UserAddress userAddress = userAddressMapper.loadById(addressId);
        OrderAddress orderAddress = initOrderAddress(adoptOrder, userAddress);
        orderAddressMapper.save(orderAddress);

        // 生成支付账单
        PayBill payBill = initPayBill(payMethod, user, adoptOrder);

        QuartzJobInfo jobInfo = new QuartzJobInfo();
        jobInfo.setJobName(QuartzConsts.PAY_OVER_TIME_ADOPT_ORDER + adoptOrder.getId());
        Map<String, Object> quartzMap = new HashMap<>();
        quartzMap.put("type", QuartzConsts.PAY_OVER_TIME_ADOPT_ORDER);
        quartzMap.put("orderId", adoptOrder.getId());
        jobInfo.setParams(quartzMap);
        jobInfo.setFireDate(adoptOrder.getLastPayTime());
        quartzService.addJob(jobInfo);


        // 支付是另一个模块，应该调用统一的支付接口而不是直接调用mapper层
        String payData = payBillService.payRequest(payBill);
        System.out.println(payData);
        return payData;
    }

    private PayBill initPayBill(Integer payMethod, User user, AdoptOrder adoptOrder) {
        // 支付 先生成支付单
        PayBill payBill = new PayBill();
        payBill.setDigest(adoptOrder.getDigest());
        payBill.setMoney(adoptOrder.getPrice());
        payBill.setUnionPaySn(adoptOrder.getPaySn());
        // 设置支付账单状态
        payBill.setState(Payconsts.PAY_STATE_TOBEPAID);
        payBill.setLastPayTime(new Date(System.currentTimeMillis()+Payconsts.PAY_TIME_OUT));
        payBill.setPayChannel(payMethod);
        payBill.setBusinessType(Payconsts.BUSINESS_TYPE_ADOPT);
        // 设置支付账单的关联订单id
        payBill.setBusinessKey(adoptOrder.getId());
        payBill.setUser_id(adoptOrder.getUser_id());
        payBill.setShop_id(adoptOrder.getShop_id());
        payBill.setNickName(user.getUsername());
        return payBill;
    }

    @Override
    public PageList<AdoptOrder> admin(AdoptOrderQuery query, LoginInfo loginInfo) {
        Employee employee = employeeMapper.loadByLoginInfoId(loginInfo.getId());
        if(employee.getShop_id()!= null){
            query.setShopId(employee.getShop_id());
        }
        return super.queryPageData(query);
    }

    @Override
    public PageList<AdoptOrder> user(AdoptOrderQuery query, LoginInfo loginInfo) {
        User user = userMapper.queryByLoginInfoId(loginInfo.getId());
        query.setUserId(user.getId());
        return super.queryPageData(query);
    }

    @Override
    public AdoptOrder queryByUnionPaySn(String unionPaySn) {
        return adoptOrderMapper.queryByUnionPaySn(unionPaySn);
    }

    @Override
    public void deleteQuartzJobByOrderId(Long orderId) {
        AdoptOrder adoptOrder = adoptOrderMapper.loadById(orderId);
        if(adoptOrder.getState() ==0){
            adoptOrder.setState(OrderConsts.ORDER_STATE_CANCEL);
            // 这里可以考虑直接上架宠物  @TODO
            adoptOrderMapper.update(adoptOrder);
            System.out.println("quartz 触发后取消编号为：" + orderId + "的订单");
        }
    }

    private OrderAddress initOrderAddress(AdoptOrder adoptOrder, UserAddress userAddress) {
        OrderAddress orderAddress = new OrderAddress();
        // 通过用户详细地址复制到地址订单中
        BeanUtils.copyProperties(userAddress,orderAddress);
        // 关联订单表id
        orderAddress.setOrder_id(adoptOrder.getId());
        // 记录订单唯一标识
        orderAddress.setOrderSn(adoptOrder.getOrderSn());
        return orderAddress;
    }

    private AdoptOrder initAdoptOrder(Pet pet, User user,Integer serviceMethod) {
        AdoptOrder order = new AdoptOrder();
        // 设置订单摘要信息
        order.setDigest("[摘要]对"+pet.getName()+"领养订单！");
        // 设置订单的状态
        order.setState(0);//待支付
        // 设置订单收购成本价格
        order.setPrice(pet.getCostprice());
        // 通过工具类CodeGenerateUtils的generateOrderSn()方法生成订单的唯一编号
        String orderSn = CodeGenerateUtils.generateOrderSn(user.getId());
        // 设置订单的唯一编号
        order.setOrderSn(orderSn);
        // 设置订单中的宠物id
        order.setPet_id(pet.getId());
        // 设置宠物售价
        order.setPrice(pet.getSaleprice());
        // 设置订单中的前任主人的id信息
        order.setUser_id(user.getId());
        // 设置最后支付时间
        order.setLastPayTime(new Date(System.currentTimeMillis()+Payconsts.PAY_TIME_OUT));
        // 记录物流方式
        order.setService_method(serviceMethod);
        // 设置订单中收购店铺的id
        order.setShop_id(pet.getShop_id());
        // 生成统一支付单号，订单和支付单都需要所以现在订单中生成
        String unionPaySn = CodeGenerateUtils.generateUnionPaySn();
        order.setPaySn(unionPaySn);
        return order;
    }
}
